package cn.liumouren.tool.security.autoconfigure.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * jwt工具类
 *
 * @author Daniel Liu
 * @date 2021/3/13 19:47
 */
public class JwtUtil {

    /**
     * 默认permissions key
     */
    public static final String DEFAULT_PERMISSIONS_KEY = "permissions";

    /**
     * 采用默认算法
     */
    public static final Algorithm DEFAULT_ALGORITHM = Algorithm.none();

    /**
     * 采用默认加密算法, 生成jwt
     *
     * @param id          id
     * @param subject     subject
     * @param duration    过期时间(ttl)
     * @param permissions permissions
     * @return jwt
     */
    public static String encrypt(String id, String subject, Duration duration, List<String> permissions) {
        return encrypt(id, subject, DEFAULT_ALGORITHM, duration, permissions);
    }

    /**
     * 采用指定加密算法, 生成jwt
     *
     * @param id          id
     * @param subject     subject
     * @param algorithm   指定算法
     * @param duration    过期时间(ttl)
     * @param permissions permissions
     * @return jwt
     */
    public static String encrypt(String id, String subject, Algorithm algorithm, Duration duration, List<String> permissions) {
        return JWT.create()
                .withJWTId(id)
                .withSubject(subject)
                .withClaim(DEFAULT_PERMISSIONS_KEY, permissions)
                .withExpiresAt(new Date(System.currentTimeMillis() + duration.toMillis()))
                .sign(algorithm);
    }

    /**
     * 采用指定加密算法, 生成jwt
     * 并添加自定义 Claim
     *
     * @param id          id
     * @param subject     subject
     * @param algorithm   指定算法
     * @param duration    过期时间(ttl)
     * @param permissions permissions
     * @param custom      自定义key
     * @param customMap   自定义数据
     * @return jwt
     */
    public static String encrypt(String id, String subject, Algorithm algorithm, Duration duration, List<String> permissions, String custom, Map<String, Object> customMap) {
        return JWT.create()
                .withJWTId(id)
                .withSubject(subject)
                .withClaim(DEFAULT_PERMISSIONS_KEY, permissions)
                .withClaim(custom, customMap)
                .withExpiresAt(new Date(System.currentTimeMillis() + duration.toMillis()))
                .sign(algorithm);
    }


    /**
     * 采用默认加密方式解析token
     *
     * @param token token
     * @return DecodedJWT
     */
    public static DecodedJWT parse(String token) {
        return parse(token, DEFAULT_ALGORITHM);
    }

    /**
     * 采用指定加密方式解析token
     *
     * @param token     token
     * @param algorithm Algorithm
     * @return DecodedJWT
     */
    public static DecodedJWT parse(String token, Algorithm algorithm) {
        return JWT.require(algorithm)
                .build()
                .verify(token);
    }

}
